package uk.ac.lkl.common.associator.ui;




import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;


public class LinkHighlighter {

    private NewAssociatorView associatorView;

    private AssociationViewLink highlightedLink;


    public LinkHighlighter(
                           NewAssociatorView associatorView) {
        this.associatorView = associatorView;

        associatorView.addMouseMotionListener(new MouseMotionAdapter() {

            public void mouseMoved(MouseEvent e) {
                processMouseMoved(e);
            }
        });
        associatorView.addMouseListener(new MouseAdapter() {

            public void mouseExited(MouseEvent e) {
                processMouseExited(e);
            }
        });
    }


    private void processMouseMoved(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();

        AssociationViewLink closestLink = null;
        Double minDistance = null;

        // repeating work here getting the lines
        for (AssociationViewLink link : associatorView.getLinks()) {
            AssociationViewPanel sourcePanel = link.getSource();
            AssociationViewPanel destinationPanel = link.getDestination();

            Rectangle leftBounds = sourcePanel.getBounds();
            Rectangle rightBounds = destinationPanel.getBounds();

            int x1 = leftBounds.x + leftBounds.width;
            int y1 = leftBounds.y + leftBounds.height / 2;
            int x2 = rightBounds.x;
            int y2 = rightBounds.y + rightBounds.height / 2;
            Line2D.Double line = new Line2D.Double(x1, y1, x2, y2);

            double distance = line.ptSegDist(x, y);

            if (minDistance == null || distance < minDistance) {
                minDistance = distance;
                closestLink = link;
            }
        }

        if (minDistance == null)
            return;

        if (minDistance > 15) {
            clearHighlight();
            return;
        }

        if (closestLink == highlightedLink)
            return;

        highlightedLink = closestLink;
        associatorView.repaint();
    }


    // don't highlight if not on component
    private void processMouseExited(MouseEvent e) {
        clearHighlight();
    }


    private void clearHighlight() {
        highlightedLink = null;
        associatorView.repaint();
    }


    public AssociationViewLink getHighlightedLink() {
        return highlightedLink;
    }

}
